import BigNumber from "bignumber.js";

import { SMALLINT_PG, BIGINT_PG } from "qqlx-core";

import { toNumber, toString } from "@lib/com.verify";
import { toMultiplySafe } from "@lib/com.amount";

export class TransformerSmallInt {
  private trans(mess: any) {
    const value = Math.min(32767, Math.max(-32767, toNumber(mess)));
    return toMultiplySafe(value);
  }

  to(mess: any): SMALLINT_PG {
    return this.trans(mess);
  }

  from(mess: any): SMALLINT_PG {
    return this.trans(mess);
  }
}

export class TransformerInteger {
  muti = 1;
  nullable = false;
  constructor(muti: number = 1, options?: { nullable: boolean }) {
    this.muti = muti;
    this.nullable = options?.nullable ?? false;
  }

  private getValieInt(mess: any) {
    return Math.min(2147483647, Math.max(-2147483647, toNumber(mess)));
  }

  to(mess: any) {
    const charge1 = this.nullable && mess === null;
    return charge1 ? null : toMultiplySafe(this.getValieInt(mess), this.muti);
  }

  from(mess: any) {
    const charge1 = this.nullable && mess === null;
    return charge1 ? null : this.getValieInt(mess);
  }
}

const MAX_BIGINT = BigInt("9223372036854775807");
const MIN_BIGINT = BigInt("-9223372036854775807");

export class TransformerBigInteger {
  muti = 1;
  constructor(muti: number = 1) {
    this.muti = muti;
  }

  to(mess: any): BIGINT_PG {
    const int = this.getBigInt(toMultiplySafe(mess, this.muti));
    const muti = BigInt(int);
    return this.limit(muti);
  }

  from(mess: any): BIGINT_PG {
    const int = this.getBigInt(mess);
    return this.limit(int);
  }

  private limit(mess: bigint) {
    if (mess >= MAX_BIGINT) return MAX_BIGINT.toString();
    else if (mess <= MIN_BIGINT) return MIN_BIGINT.toString();
    else return mess.toString();
  }

  private getBigInt(mess: any) {
    const big = { value: BigInt("-1") };
    big.value = BigInt(toString(mess));
    return big.value;
  }
}
